<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="test">尚硅谷IT教育</div>

<div id="app">
  <ul>
    <li>test1</li>
    <li>test2</li>
    <li>test3</li>
  </ul>
</div>



<!--
1. [].slice.call(lis): 将伪数组转换为真数组
2. node.nodeType: 得到节点类型
3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
6. DocumentFragment: 文档碎片(高效批量更新多个节点)
-->

<script type="text/javascript">
// 1. [].slice.call(lis): 将伪数组转换为真数组
// 伪数组 arguments NodeList
function fn(){
  console.log(arguments);
  console.log(Array.from(arguments)); // ES6
  console.log([].slice.call(arguments)); 
  console.log(Array.prototype.slice.call(arguments)); 
}
fn(1, 2, 3)

// 2. node.nodeType: 得到节点类型
const lis = document.querySelectorAll('li')
console.log(lis[0].nodeType); // 元素节点：1
console.dir(lis[0].childNodes[0].nodeType); // 文本节点：3

// 3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
const person = { name: 'jack' }
// Object.defineProperty(person, 'name', {
//   value: 'xxx', // 属性值
//   writable: true, // 是否可写
//   enumerable: true, // 是否可枚举、遍历 for in
//   configurable: true, // 是否可重新配置和删除 delete
// })

Object.defineProperty(person, 'name', {
  enumerable: true, // 是否可枚举、遍历 for in
  configurable: true, // 是否可重新配置和删除 delete
  get() {}, // 读取属性调用get
  set(val) { // 设置属性值调用set
    // 更新数据
    // 更新视图
    // 就实现响应式了
  } 
})


// 4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
const obj = {a: 1, b: 2} 
obj.__proto__.c = 3 // 没有
console.log(Object.keys(obj)); // ['a', 'b']
console.log(Object.values(obj));
// 用来遍历对象
// for in
// 第二种方式
Object.keys(obj).forEach((key) => {
  console.log(key, obj[key]);
})

// 5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
const $$hasOwnProperty = Object.prototype.hasOwnProperty
// const $$hasOwnProperty = function (a, b) {
//   return Object.prototype.hasOwnProperty.call(a, b)
// }
// console.log(obj);
for (const key in obj) {
  // if (obj.hasOwnProperty(key)) {
  //   console.log(key);
  // }
  if ($$hasOwnProperty.call(obj, key)) {
    console.log(key);
  }
  // if ($$hasOwnProperty(obj, key)) {
  //   console.log(key);
  // }
}

// 6. DocumentFragment: 文档碎片(高效批量更新多个节点)
// 创建空的文档碎片节点
const fragment = document.createDocumentFragment()
const app = document.getElementById('app')

// 将DOM元素添加到文档碎片节点中
// DOM元素就会自动从DOM树移除
fragment.appendChild(app.children[0]);

// fragment.childNodes.forEach(() => {})

// 操作DOM
[].slice.call(fragment.childNodes[0].children).forEach((li) => {
  return li.textContent += '~~~'
})

// 添加回去
app.appendChild(fragment)
// console.dir(fragment);

</script>
</body>
</html>